package ge.telasi.tasks.ui.comp;

import ge.telasi.tasks.ui.UIUtils;
import ge.telasi.tasks.ui.log.Logger;
import ge.telasi.tasks.ui.log.LoggerUtils;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

/**
 * @author dimitri
 */
public abstract class SimplePanel extends JPanel implements Logger {
    private CardLayout layout;
    
    protected JTextArea txtError;
    protected JComponent mainComponent;

    public SimplePanel() {
        initComponents();
        showWait();
    }

    public void showWait() {
        layout.show(this, "wait");
        doLayout();
    }

    public void showError(Exception ex) {
        LoggerUtils.manageException(this, this, ex);
        layout.show(this, "error");
        doLayout();
    }

    public void showLock() {
        layout.show(this, "lock");
        doLayout();
    }

    public void showMain() {
        layout.show(this, "main");
        doLayout();
    }

    private void initComponents() {
        layout = new CardLayout();
        setLayout(layout);
        add(createWaitPanel(), "wait");
        add(createErrorPanel(), "error");
        add(createLockPanel(), "lock");
        mainComponent = createMainComponent();
        add(mainComponent, "main");
    }

    private JComponent createWaitPanel() {
        JPanel waitPanel = new JPanel(new GridBagLayout());
        ImageIcon waitIcon = UIUtils.getIcon16x16("hourglass.png");
        JLabel waitLabel = new AnimatedLabel("გთხოვთ დაელოდოთ...");
        Font oldFont = waitLabel.getFont();
        Font newFont = new Font(oldFont.getFamily(), Font.ITALIC, oldFont.getSize() + 3);
        waitLabel.setIcon(waitIcon);
        waitLabel.setFont(newFont);
        waitPanel.add(waitLabel);
        return waitPanel;
    }

    private JComponent createErrorPanel() {
        JPanel errorPanel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.insets = new Insets(0, 0, 20, 0);
        // label
        ImageIcon waitIcon = UIUtils.getIcon16x16("cancel.png");
        JLabel waitLabel = new JLabel("გაუთვალისწინებელი შეცდომა");
        Font oldFont = waitLabel.getFont();
        Font newFont = new Font(oldFont.getFamily(), Font.ITALIC, oldFont.getSize() + 3);
        waitLabel.setIcon(waitIcon);
        waitLabel.setFont(newFont);
        errorPanel.add(waitLabel, c);
        // error text
        txtError = new JTextArea();
        txtError.setWrapStyleWord(true);
        txtError.setLineWrap(true);
        txtError.setEditable(false);
        txtError.setBorder(null);
        txtError.setForeground(Color.RED);
        JScrollPane scroll = new JScrollPane(txtError);
        scroll.setPreferredSize(new Dimension(400, 200));
        scroll.setOpaque(false);
        txtError.setOpaque(false);
        errorPanel.add(scroll, c);
        return errorPanel;
    }

    private JComponent createLockPanel() {
        JPanel waitPanel = new JPanel(new GridBagLayout());
        ImageIcon waitIcon = UIUtils.getIcon16x16("lock.png");
        JLabel waitLabel = new AnimatedLabel("არანაირი მოქმედება...");
        Font oldFont = waitLabel.getFont();
        Font newFont = new Font(oldFont.getFamily(), Font.ITALIC, oldFont.getSize() + 3);
        waitLabel.setIcon(waitIcon);
        waitLabel.setFont(newFont);
        waitPanel.add(waitLabel);
        return waitPanel;
    }

    public void clearPanel() {
        txtError.setText("");
    }

    public void showError(String error) {
        txtError.setText(error);
        txtError.setCaretPosition(0);
    }

    protected abstract JComponent createMainComponent();
    protected abstract boolean serverCommunicationProcess() throws Exception;
    protected abstract void serverCommunicationComplete();

    public boolean doServerCommunication() {
        try {
            showWait();
            if (serverCommunicationProcess()) {
                serverCommunicationComplete();
                showMain();
                return true;
            } else {
                showLock();
                return false;
            }
        } catch (Exception ex) {
            showError(ex);
            return false;
        }
    }

}
